﻿namespace Community.CsharpSqlite.Entity
{
    /*
    ** CAPI3REF: Mutex Handle
    **
    ** The mutex module within SQLite defines [sqlite3_mutex] to be an
    ** abstract type for a mutex object.  The SQLite core never looks
    ** at the internal representation of an [sqlite3_mutex].  It only
    ** deals with pointers to the [sqlite3_mutex] object.
    **
    ** Mutexes are created using [MutexHelper.sqlite3_mutex_alloc()].
    */
    //typedef struct sqlite3_mutex sqlite3_mutex;

    /*
    ** CAPI3REF: OS Interface Object
    **
    ** An instance of the sqlite3_vfs object defines the interface between
    ** the SQLite core and the underlying operating system.  The "vfs"
    ** in the name of the object stands for "virtual file system".
    **
    ** The value of the iVersion field is initially 1 but may be larger in
    ** future versions of SQLite.  Additional fields may be appended to this
    ** object when the iVersion value is increased.  Note that the structure
    ** of the sqlite3_vfs object changes in the transaction between
    ** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
    ** modified.
    **
    ** The szOsFile field is the size of the subclassed [sqlite3_file]
    ** structure used by this VFS.  mxPathname is the maximum length of
    ** a pathname in this VFS.
    **
    ** Registered sqlite3_vfs objects are kept on a linked list formed by
    ** the pNext pointer.  The [sqlite3_vfs_register()]
    ** and [sqlite3_vfs_unregister()] interfaces manage this list
    ** in a thread-safe way.  The [sqlite3_vfs_find()] interface
    ** searches the list.  Neither the application code nor the VFS
    ** implementation should use the pNext pointer.
    **
    ** The pNext field is the only field in the sqlite3_vfs
    ** structure that SQLite will ever modify.  SQLite will only access
    ** or modify this field while holding a particular static mutex.
    ** The application should never modify anything within the sqlite3_vfs
    ** object once the object has been registered.
    **
    ** The zName field holds the name of the VFS module.  The name must
    ** be unique across all VFS modules.
    **
    ** SQLite will guarantee that the zFilename parameter to xOpen
    ** is either a NULL pointer or string obtained
    ** from xFullPathname().  SQLite further guarantees that
    ** the string will be valid and unchanged until xClose() is
    ** called. Because of the previous sentence,
    ** the [sqlite3_file] can safely store a pointer to the
    ** filename if it needs to remember the filename for some reason.
    ** If the zFilename parameter is xOpen is a NULL pointer then xOpen
    ** must invent its own temporary name for the file.  Whenever the 
    ** xFilename parameter is NULL it will also be the case that the
    ** flags parameter will include [FileOpenOperation.SQLITE_OPEN_DELETEONCLOSE].
    **
    ** The flags argument to xOpen() includes all bits set in
    ** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
    ** or [sqlite3_open16()] is used, then flags includes at least
    ** [FileOpenOperation.SQLITE_OPEN_READWRITE] | [FileOpenOperation.SQLITE_OPEN_CREATE]. 
    ** If xOpen() opens a file read-only then it sets *pOutFlags to
    ** include [FileOpenOperation.SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
    **
    ** SQLite will also add one of the following flags to the xOpen()
    ** call, depending on the object being opened:
    **
    ** <ul>
    ** <li>  [FileOpenOperation.SQLITE_OPEN_MAIN_DB]
    ** <li>  [FileOpenOperation.SQLITE_OPEN_MAIN_JOURNAL]
    ** <li>  [FileOpenOperation.SQLITE_OPEN_TEMP_DB]
    ** <li>  [FileOpenOperation.SQLITE_OPEN_TEMP_JOURNAL]
    ** <li>  [FileOpenOperation.SQLITE_OPEN_TRANSIENT_DB]
    ** <li>  [FileOpenOperation.SQLITE_OPEN_SUBJOURNAL]
    ** <li>  [FileOpenOperation.SQLITE_OPEN_MASTER_JOURNAL]
    ** </ul>
    **
    ** The file I/O implementation can use the object type flags to
    ** change the way it deals with files.  For example, an application
    ** that does not care about crash recovery or rollback might make
    ** the open of a journal file a no-op.  Writes to this journal would
    ** also be no-ops, and any attempt to read the journal would return
    ** StatusCode.SQLITE_IOERR.  Or the implementation might recognize that a database
    ** file will be doing page-aligned sector reads and writes in a random
    ** order and set up its I/O subsystem accordingly.
    **
    ** SQLite might also add one of the following flags to the xOpen method:
    **
    ** <ul>
    ** <li> [FileOpenOperation.SQLITE_OPEN_DELETEONCLOSE]
    ** <li> [FileOpenOperation.SQLITE_OPEN_EXCLUSIVE]
    ** </ul>
    **
    ** The [FileOpenOperation.SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
    ** deleted when it is closed.  The [FileOpenOperation.SQLITE_OPEN_DELETEONCLOSE]
    ** will be set for TEMP  databases, journals and for subjournals.
    **
    ** The [FileOpenOperation.SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
    ** with the [FileOpenOperation.SQLITE_OPEN_CREATE] flag, which are both directly
    ** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
    ** API.  The FileOpenOperation.SQLITE_OPEN_EXCLUSIVE flag, when paired with the 
    ** FileOpenOperation.SQLITE_OPEN_CREATE, is used to indicate that file should always
    ** be created, and that it is an error if it already exists.
    ** It is <i>not</i> used to indicate the file should be opened 
    ** for exclusive access.
    **
    ** At least szOsFile bytes of memory are allocated by SQLite
    ** to hold the  [sqlite3_file] structure passed as the third
    ** argument to xOpen.  The xOpen method does not have to
    ** allocate the structure; it should just fill it in.  Note that
    ** the xOpen method must set the sqlite3_file.pMethods to either
    ** a valid [sqlite3_io_methods] object or to NULL.  xOpen must do
    ** this even if the open fails.  SQLite expects that the sqlite3_file.pMethods
    ** element will be valid after xOpen returns regardless of the success
    ** or failure of the xOpen call.
    **
    ** The flags argument to xAccess() may be [AccessFlag.SQLITE_ACCESS_EXISTS]
    ** to test for the existence of a file, or [AccessFlag.SQLITE_ACCESS_READWRITE] to
    ** test whether a file is readable and writable, or [AccessFlag.SQLITE_ACCESS_READ]
    ** to test whether a file is at least readable.   The file can be a
    ** directory.
    **
    ** SQLite will always allocate at least mxPathname+1 bytes for the
    ** output buffer xFullPathname.  The exact size of the output buffer
    ** is also passed as a parameter to both  methods. If the output buffer
    ** is not large enough, [StatusCode.SQLITE_CANTOPEN] should be returned. Since this is
    ** handled as a fatal error by SQLite, vfs implementations should endeavor
    ** to prevent this by setting mxPathname to a sufficiently large value.
    **
    ** The xRandomness(), xSleep(), and xCurrentTime() interfaces
    ** are not strictly a part of the filesystem, but they are
    ** included in the VFS structure for completeness.
    ** The xRandomness() function attempts to return nBytes bytes
    ** of good-quality randomness into zOut.  The return value is
    ** the actual number of bytes of randomness obtained.
    ** The xSleep() method causes the calling thread to sleep for at
    ** least the number of microseconds given.  The xCurrentTime()
    ** method returns a Julian Day Number for the current date and time.
    **
    */
    //typedef struct sqlite3_vfs sqlite3_vfs;
    //struct sqlite3_vfs {
    //  int iVersion;            /* Structure version number */
    //  int szOsFile;            /* Size of subclassed sqlite3_file */
    //  int mxPathname;          /* Maximum file pathname length */
    //  sqlite3_vfs *pNext;      /* Next registered VFS */
    //  const char *zName;       /* Name of this virtual file system */
    //  void *pAppData;          /* Pointer to application-specific data */
    //  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
    //               int flags, int *pOutFlags);
    //  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
    //  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
    //  int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
    //  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
    //  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
    //  void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
    //  void (*xDlClose)(sqlite3_vfs*, void*);
    //  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
    //  int (*xSleep)(sqlite3_vfs*, int microseconds);
    //  int (*xCurrentTime)(sqlite3_vfs*, double*);
    //  int (*xGetLastError)(sqlite3_vfs*, int, char *);
    //  /* New fields may be appended in figure versions.  The iVersion
    //  ** value will increment whenever this happens. */
    //};
    public class sqlite3_vfs
    {
        public int iVersion; /* Structure version number */
        public int mxPathname; /* Maximum file pathname length */
        public object pAppData; /* Pointer to application-specific data */
        public sqlite3_vfs pNext; /* Next registered VFS */
        public int szOsFile; /* Size of subclassed sqlite3_file */
        public dxAccess xAccess;
        public dxCurrentTime xCurrentTime;
        public dxDelete xDelete;
        public dxDlClose xDlClose;
        public dxDlError xDlError;
        public dxDlOpen xDlOpen;
        public dxDlSym xDlSym;
        public dxFullPathname xFullPathname;
        public dxGetLastError xGetLastError;
        public dxOpen xOpen;
        public dxRandomness xRandomness;
        public dxSleep xSleep;
        public string zName; /* Name of this virtual file system */
        /* New fields may be appended in figure versions.  The iVersion
        ** value will increment whenever this happens. */

        public sqlite3_vfs()
        {
        }

        public sqlite3_vfs(int iVersion,
                           int szOsFile,
                           int mxPathname,
                           sqlite3_vfs pNext,
                           string zName,
                           object pAppData,
                           dxOpen xOpen,
                           dxDelete xDelete,
                           dxAccess xAccess,
                           dxFullPathname xFullPathname,
                           dxDlOpen xDlOpen,
                           dxDlError xDlError,
                           dxDlSym xDlSym,
                           dxDlClose xDlClose,
                           dxRandomness xRandomness,
                           dxSleep xSleep,
                           dxCurrentTime xCurrentTime,
                           dxGetLastError xGetLastError)
        {
            this.iVersion = iVersion;
            this.szOsFile = szOsFile;
            this.mxPathname = mxPathname;
            this.pNext = pNext;
            this.zName = zName;
            this.pAppData = pAppData;
            this.xOpen = xOpen;
            this.xDelete = xDelete;
            this.xAccess = xAccess;
            this.xFullPathname = xFullPathname;
            this.xDlOpen = xDlOpen;
            this.xDlError = xDlError;
            this.xDlSym = xDlSym;
            this.xDlClose = xDlClose;
            this.xRandomness = xRandomness;
            this.xSleep = xSleep;
            this.xCurrentTime = xCurrentTime;
            this.xGetLastError = xGetLastError;
        }
    }
}